package cn.xcyy.itcc.service.impl;

import cn.xcyy.itcc.constants.CommonConstants;
import cn.xcyy.itcc.constants.SmsCodeConstants;
import cn.xcyy.itcc.dto.SmsCodeDto;
import cn.xcyy.itcc.enums.GlodalErrorCode;
import cn.xcyy.itcc.exception.GlobalCustomException;
import cn.xcyy.itcc.mapper.MessageSmsMapper;
import cn.xcyy.itcc.service.IVerifyCodeSerivce;
import cn.xcyy.itcc.util.AssertUtil;
import cn.xcyy.itcc.util.StrUtils;
import cn.xcyy.itcc.util.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeSerivceImpl implements IVerifyCodeSerivce {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private MessageSmsMapper messageSmsMapper;

    @Override
    public String imgKey(String key) {
        String code = VerifyCodeUtils.generateVerifyCode(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        return VerifyCodeUtils.verifyCode(115,40,code);
    }

    @Override
    public void smsCode(SmsCodeDto smsCodeDto) {
        //一：校验
        //1.空值校验
        String imageCode = smsCodeDto.getImageCode();
        String phone = smsCodeDto.getPhone();
        String imageCodeKey = smsCodeDto.getImageCodeKey();

        //校检用户填写手机号的格式是否正确
        AssertUtil.isPhone(phone,GlodalErrorCode.PARAM_IS_PHONE_NULL_ERROR);

        //校检前端图形验证码是否为空
        AssertUtil.isNotEmpty(imageCode,GlodalErrorCode.PARAM_IS_GRAPH_NULL_ERROR);
        
        //2.校检图形验证码 - 从Redis中获取图形验证码
        String graphCode = redisTemplate.opsForValue().get(imageCodeKey).toString();

        //2.2判断图形验证码是否过期
        AssertUtil.isNotNull(graphCode,GlodalErrorCode.PARAM_IS_EXPIRED_ERROR);

        //2.3图形验证码是否正确
        AssertUtil.isEqualsIgnoreCase(graphCode,imageCode,GlodalErrorCode.PARAM_IS_FALSE_ERROR);

        //3.手机号码是否注册过
//        User user = userMapper.loadByPhone(phone);if (user!=null){ throw new GlobalCustomException("该手机号已被使用！");}@TODO

        //二：获取手机验证码，判断是否过期
        String key = String.format(CommonConstants.Register_PHONE_PREFIX, phone);

        Object codeObj = redisTemplate.opsForValue().get(key);

        //1.过期了或者没有验证码  -  使用工具类重新生成
        String smsCodeObj = null;

        Date date = new Date();

        if (codeObj==null){
            //生成4位数的手机验证码
            smsCodeObj = StrUtils.getRandomString(6);
        }else {
            String[] split = codeObj.toString().split(":");

            //2.没有过期
            Long time =  Long.parseLong(codeObj.toString().split(":")[1]);
            boolean b = (date.getTime() - time) < 60000;
            AssertUtil.isFalse(b,GlodalErrorCode.NO);

            //2.3.如果过了重发时间 - 使用以前的验证码
            smsCodeObj = split[0];
        }

        //3.保存Redis - 重新设置3分钟
        redisTemplate.opsForValue().set("register:"+phone,smsCodeObj+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //4.调用工具类发送短信 - sout打印
        System.out.println(smsCodeObj);
    }

}
